<!-- 通用图片上传组件 -->
<template>
  <div class="w-main" :class="isCenter ? 'flex-center' : ''">
    <el-upload
      v-if="!form[imageKey]"
      :accept="accept"
      :action="UPLOAD_URL"
      :data="uploadData"
      :show-file-list="false"
      :on-error="handleResourcesUploadError"
      :on-success="(response: IUpdateSuccessData, file: UploadFile) => handleResourcesUploadSuccess(response, file, successCallback)"
      :before-upload="file => handleBeforeUpload({ file, limit, fileType: accept })">
      <el-icon class="uploader-icon">
        <Plus />
      </el-icon>
    </el-upload>
    <div class="w-continer-img" v-else>
      <img :src="form[imageKey] ? IMG_URL + form[imageKey] : ''" alt="图片" class="w-img" />
      <div class="icon-view-close-info">
        <el-icon class="icon-close" @click="handleShowImg">
          <ZoomIn />
        </el-icon>
        <el-icon class="icon-close" @click="handleDeleteImage">
          <Delete />
        </el-icon>
      </div>
    </div>
    <p>{{ suggestInfo }}</p>
  </div>
  <el-dialog title="查看" width="30%" append-to-body v-model="dialogImage">
    <img width="100%" :src="dialogImageUrl" alt="主图" />
  </el-dialog>
</template>
<script setup lang="ts" generic="T extends Record<string, any>, K extends keyof T">
import { useUpload } from "@/hooks/useUpload";
import type { IUpdateSuccessData } from "@/types/upload";
import { IMG_URL, UPLOAD_URL } from "@/utils/config";
import type { UploadFile } from "element-plus";
type AcceptType = ".png" | ".jpg" | ".jpeg" | ".gif";
interface Props {
  imageKey: K /* 图片key */;
  limit?: number /* 图片大小限制信息 */;
  acceptList?: AcceptType[] /* 图片类型限制信息 */;
  suggestInfo?: string /* 提示信息 */;
  imageWidth?: number /* 修改图片宽度尺寸 */;
  imageHeight?: number /* 修改图片高度尺寸 */;
  isCenter?: boolean /* 是否居中显示（用在规格图片上） */;
}
const { imageKey, acceptList = [".png", ".jpg", ".jpeg", ".gif"], suggestInfo = "建议：尺寸300*300,大小500k以下", limit = 500, imageWidth = 108, imageHeight = 108, isCenter = false } = defineProps<Props>();
const accept = ref<string>(acceptList.join(","));
const disabledbtn = defineModel<boolean>("disabledbtn", { required: true });
const loading = defineModel<boolean>("loading", { required: true });
const form = defineModel<T>("form", { required: true });
const emit = defineEmits<{
  handleDeleteImage: [];
  successCallback: [];
}>();
let { uploadData, handleResourcesUploadSuccess, handleBeforeUpload, handleResourcesUploadError } = useUpload({ disabledbtn, loading });

const dialogImage = ref(false);
/* 图片预览地址 */
const dialogImageUrl = computed(() => {
  return IMG_URL + form.value[imageKey];
});
/* 删除图片 */
function handleDeleteImage() {
  /* 通过类型断言，明确告知ts，将""视为T[K]类型 */
  form.value[imageKey] = "" as T[K];
  emit("handleDeleteImage");
}
/* 显示图片 */
function handleShowImg() {
  dialogImage.value = true;
}
/* 上传成功回调 */
function successCallback(res: IUpdateSuccessData) {
  form.value[imageKey] = ("/" + res.key) as T[K];
  ElMessage.success("上传成功");
  emit("successCallback");
}
</script>

<style lang="scss" scoped>
/* 图片上传 start */
:deep(.el-upload--text) {
  width: inherit;
  height: inherit;
}
.w-main {
  // 定义变量
  $imageWidth: v-bind('imageWidth+"px"');
  $imageHeight: v-bind('imageHeight+"px"');
  $imageLineHeight: v-bind('imageHeight+"px"');
  .w-continer-img {
    position: relative;
    width: $imageWidth;
    height: $imageHeight;
    line-height: $imageLineHeight;
    text-align: center;

    .w-img {
      width: inherit;
      height: inherit;
      border-radius: 5px;
    }

    .icon-close {
      display: none;
    }
    &:hover .icon-view-close-info {
      border-radius: 5px;
      opacity: 1;
    }

    .icon-view-close-info {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
      font-size: 20px;
      border-radius: 5px;
      background-color: rgba(0, 0, 0, 0.5);
      transition: opacity 0.3s;
      opacity: 0;
      .icon-close {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 30px;
        height: 30px;
        cursor: pointer;
        & + .icon-close {
          margin-left: 10px;
        }
      }
    }
  }
  .uploader-icon {
    width: $imageWidth;
    height: $imageHeight;
    line-height: $imageLineHeight;
    font-size: 28px;
    color: #8c939d;
    text-align: center;
  }
}
.flex-center {
  display: flex;
  justify-content: center;
}
/* 图片上传 end */
</style>
